﻿// Doc-Encode UTF8-BOM, Space(4), Unix(LF)
#include "man_appex/appex_ncli.h"
#include "klbmem/klb_mem.h"

namespace pfw {
//////////////////////////////////////////////////////////////////////////


#define APPEX_NCLI_HANDLE           "APPEX_NCLI_HANDLE*"    ///< Lua meta标示


typedef struct meta_ncli_t_
{
    appex_ncli_t*       p_appex;
    man_ncli_t*         p_man;
}meta_ncli_t;


///////////////////////////////////

static meta_ncli_t* new_meta_ncli(lua_State* L)
{
    meta_ncli_t* p_meta = (meta_ncli_t*)lua_newuserdata(L, sizeof(meta_ncli_t));
    KLB_MEMSET(p_meta, 0, sizeof(meta_ncli_t));
    luaL_setmetatable(L, APPEX_NCLI_HANDLE);

    return p_meta;
}

static meta_ncli_t* to_meta_ncli(lua_State* L, int index)
{
    meta_ncli_t* p_meta = (meta_ncli_t*)luaL_checkudata(L, index, APPEX_NCLI_HANDLE);
    luaL_argcheck(L, NULL != p_meta, index, "'ncli' expected");
    return p_meta;
}

static int meta_ncli_gc(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    return 0;
}

static int meta_ncli_tostring(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    lua_pushfstring(L, "nser:%p", p_meta);
    return 1;
}

///////////////////////////////////

static int meta_ncli_init(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    int ret = man_ncli_init(p_meta->p_man);

    lua_pushinteger(L, ret);
    return 1;
}

static int meta_ncli_quit(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    man_ncli_quit(p_meta->p_man);

    return 0;
}

static int meta_ncli_start(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    int ret = man_ncli_start(p_meta->p_man);

    lua_pushinteger(L, ret);
    return 1;
}

static int meta_ncli_stop(lua_State* L)
{
    meta_ncli_t* p_meta = to_meta_ncli(L, 1);

    man_ncli_stop(p_meta->p_man);

    return 0;
}

///////////////////////////////////
// meta ncli 接口

static void appex_ncli_createmeta(lua_State* L)
{
    static luaL_Reg meth[] = {
        { "close",              meta_ncli_gc },         // 关闭 meta(句柄)

        { "init",               meta_ncli_init },       // 模块初始化
        { "quit",               meta_ncli_quit },       // 模块退出

        { "start",              meta_ncli_start },      // 模块开始(线程)
        { "stop",               meta_ncli_stop },       // 模块停止(线程)

        { NULL,                 NULL }
    };

    static const luaL_Reg metameth[] = {
        { "__index",            NULL },  /* place holder */
        { "__gc",               meta_ncli_gc },
        { "__close",            meta_ncli_gc },
        { "__tostring",         meta_ncli_tostring },
        { NULL,                 NULL }
    };

    luaL_newmetatable(L, APPEX_NCLI_HANDLE);/* metatable for APPEX_NCLI_HANDLE handles */
    luaL_setfuncs(L, metameth, 0);          /* add metamethods to new metatable */
    luaL_newlibtable(L, meth);              /* create method table */
    luaL_setfuncs(L, meth, 0);              /* add file methods to method table */
    lua_setfield(L, -2, "__index");         /* metatable.__index = method table */
    lua_pop(L, 1);                          /* pop metatable */
}

//////////////////////////////////////////////////////////////////////////


static int appex_ncli_open(lua_State* L)
{
    appex_ncli_t* p_appex = appex_get_ncli2();
    man_ncli_t* p_man = appex_ncli_get_manage(p_appex);

    // !!!注意: manage 模块是唯一的, 在Lua层 许可打开多个 meta(句柄)
    // 也可能存在 多个线程 多个 meta(句柄), 操作 manage 模块 的情况

    // 创建 meta
    meta_ncli_t* p_meta = new_meta_ncli(L);

    // 初始化 参数
    p_meta->p_appex = p_appex;
    p_meta->p_man = p_man;

    return 1;
}

//////////////////////////////////////////////////////////////////////////

// 
int appex_luaopen_ncli(lua_State* L)
{
    static luaL_Reg lib[] =
    {
        { "open",               appex_ncli_open },  // 打开 meta(句柄)


        { NULL,                 NULL }
    };

    // 创建导出库函数
    luaL_newlib(L, lib);

    // APPEX_NCLI_HANDLE
    appex_ncli_createmeta(L);

    return 1; // 表示返回 1个 table
}

//////////////////////////////////////////////////////////////////////////
} // namespace pfw

//end
